package com.fsxgt.datagrid.ds.utils;
/**  
 * @Title: ParamUtil.java
 * @Description: TODO(描述)
 * @author liuyi
 * @date 2023-08-01 07:56:08 
 */


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.fsxgt.datagrid.ds.exception.ParamException;
import com.fsxgt.datagrid.ds.utils.JsqlparserUtil.SQLBean;

import lombok.Data;

public class ParamUtil {
	
	public final static String PARAM_REGEX1= "\\$\\{\\w+\\}";
	public final static String PARAM_REGEX2= "\\#\\{\\w+\\}";
	public final static String PARAM_KEY= "params";

	@Data
	public static class ParamBO {

		private String text;
		private List params;

	}


	
	public static ParamBO transform(String text, Map params) throws ParamException {

		ParamBO bo = new ParamBO();
		bo.setParams(new ArrayList());

		List<String> ss = getFindStringList(text, PARAM_REGEX1);
		for (String param : ss) {
			String p = param.substring(2, param.length() - 1);
			if (params.get(p) == null) {
//				throw new FlowException("找不到参数:" + p);
				;
			} else {
				Object obj = params.get(p);
				if(obj instanceof List) {	
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

					StringBuilder str=new StringBuilder();
					((List)obj).forEach((o)->{
						str.append(","+transformVaule(o));
					});
					if(str.length()>0) {
						text = replace(text,param,str.substring(1));
					}
				}else {
					text = replace(text,param,params.get(p).toString());
				}
			}
		}
		ss = getFindStringList(text, PARAM_REGEX2);
		
		for (String param : ss) {
			String p = param.substring(2, param.length() - 1);
			if (params.get(p) == null) {
//				throw new FlowException("找不到参数:" + p);
				;
			} else {
				Object obj = params.get(p);
				
				if(obj instanceof List) {
					StringBuilder str=new StringBuilder();
					((List)obj).forEach((o)->{
						bo.getParams().add(o);
						str.append(",?");
					});
					if(str.length()>0) {
						text = replace(text,param,str.substring(1));
					
					}
				}else {
					bo.getParams().add(obj);
					text = replace(text,param,"?");

				}
			}
		}

		bo.setText(text);

		return bo;
	}
	
	public static String replace(String str,String  s1,String s2){
		while(str.indexOf(s1)>=0) {
			str=str.substring(0, str.indexOf(s1))+s2+str.substring(str.indexOf(s1)+s1.length());
		}		
    	return str;
    }
	



	public static List<String> getFindStringList(String str, String regex) {
		List tmp = new ArrayList();

		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		while (matcher.find()) {
			tmp.add(matcher.group().toString());
		}
		return tmp;
	}
	
	private static String transformVaule(Object o) {
		
		if(o instanceof Number) {
			return o.toString();
		}else if(o instanceof Date){
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			return "'"+sdf.format((Date)o)+"'";
		}else if(o instanceof LocalDateTime){
			String v=((LocalDateTime)o).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));	
			return "'"+v+"'";
		}else {
			return "'"+o.toString()+"'";
		}

	}
	/**
     * 移除参数
     *
     * @param expression
     * @param expressionList
     */
	public static String removeWhere(String sql,String seat,boolean replaceAll) throws Exception {
		
		int index=1;
		Map paramIndexMap=new HashMap();
		

		List<String> params=getFindStringList(sql, PARAM_REGEX1);
		params.addAll(getFindStringList(sql, PARAM_REGEX2));
		
		for(String p:params) {
			++index;
			String iKey=String.format("PARAM_%06d", index);
			paramIndexMap.put(iKey, p);
			sql=replace(sql,p,iKey);
		}
		
		SQLBean sqlBean = JsqlparserUtil.parseExpression(sql);
		
		sql=sqlBean.getSql();
	
		
		for(String expression:sqlBean.getExpressionList()) {
			List<String> ps = getFindStringList(expression, "PARAM_\\d{6}");
			if(replaceAll){
				sql=replace(sql,expression,seat);
			}else if(ps.size()>0) {
				sql=replace(sql,expression,seat);
			}
			
		}
		
		return sql;
		
		
	}
	
	public  static String getParamValue(Class type,Object value) {
		
		String v=null;
		
		// TODO Auto-generated method stub
		if(value==null) {
			v=null;
		}else if(value instanceof Date){
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			v=sdf.format(value);
		}else if(value instanceof LocalDateTime){
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			v=((LocalDateTime) value).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
		}else {
			v=value.toString();
		}
		
		if(type==null||Number.class.isAssignableFrom(type)) {
			return v;
		}else {
			return "'"+v+"'";
		}
		
		


	}
	
	public  static String getParamName(String param) {
		
		if(param==null) {
			return null;
		}
		
		List<String> list=getFindStringList(param, PARAM_REGEX1);
		if(list.size()>0) {
			String p = list.get(0).substring(2, list.get(0).length() - 1);
			return p;
		}
		list=getFindStringList(param, PARAM_REGEX2);
		if(list.size()>0) {
			String p = list.get(0).substring(2, list.get(0).length() - 1);
			return p;
		}
		
		return null;
		
	}
	
	
	
	public  static void main(String args[]) throws Exception {
		
		List list=new ArrayList();
		
		
		System.out.println((Comparable)null);
		
//		System.out.println(ParamUtil.isParam("${aaa}"));
		
//		String sql="SELECT '二号转炉' AS converterProcess,a.TASK_COUNTER,a.HEAT_ID,b.REQ_O2_VOL AS mainBlowO,c.REQ_O2_VOL AS secBlowO ,\r\n"
//				+ "    NVL(f.MB_CALC_WGT,0) AS lime,\r\n"
//				+ "    NVL(g.MB_CALC_WGT,0) AS limestone,\r\n"
//				+ "    NVL(h.MB_CALC_WGT,0) AS mg,\r\n"
//				+ "    NVL(i.MB_CALC_WGT,0) AS magnetic,\r\n"
//				+ "    NVL(j.MB_CALC_WGT,0) AS sinter,\r\n"
//				+ "    NVL(k.MB_CALC_WGT,0) AS dolomite,\r\n"
//				+ "    NVL(l.MB_CALC_WGT,0) AS ore FROM SDM_CNV2.PGM_SCHEDULE  a\r\n"
//				+ "LEFT JOIN SDM_CNV2.PGM_PERIOD_DATA_MB  b ON a.TASK_COUNTER = b.TASK_COUNTER\r\n"
//				+ "LEFT JOIN SDM_CNV2.PGM_PERIOD_DATA_SB  c ON a.TASK_COUNTER = c.TASK_COUNTER\r\n"
//				+ "LEFT JOIN SDM_CNV2.PGM_CNV_ADDITIONS  f ON a.TASK_COUNTER = f.TASK_COUNTER AND f.MATERIAL_CODE = 101\r\n"
//				+ "LEFT JOIN SDM_CNV2.PGM_CNV_ADDITIONS  g ON a.TASK_COUNTER = g.TASK_COUNTER AND g.MATERIAL_CODE = 105\r\n"
//				+ "LEFT JOIN SDM_CNV2.PGM_CNV_ADDITIONS  h ON a.TASK_COUNTER = h.TASK_COUNTER AND h.MATERIAL_CODE = 103\r\n"
//				+ "LEFT JOIN SDM_CNV2.PGM_CNV_ADDITIONS  i ON a.TASK_COUNTER = i.TASK_COUNTER AND i.MATERIAL_CODE = 109\r\n"
//				+ "LEFT JOIN SDM_CNV2.PGM_CNV_ADDITIONS  j ON a.TASK_COUNTER = j.TASK_COUNTER AND j.MATERIAL_CODE = 110\r\n"
//				+ "LEFT JOIN SDM_CNV2.PGM_CNV_ADDITIONS  k ON a.TASK_COUNTER = k.TASK_COUNTER AND k.MATERIAL_CODE = 106\r\n"
//				+ "LEFT JOIN SDM_CNV2.PGM_CNV_ADDITIONS  l ON a.TASK_COUNTER = l.TASK_COUNTER AND l.MATERIAL_CODE = 109\r\n"
//				+ "WHERE a.HEAT_ID !='-----' AND a.TASK_COUNTER <= ${maxID2} AND a.TASK_COUNTER >=${minID2}";
//		String ss=removeParam(sql, " 1=2 ");
//		System.out.println(ss);
		

	}
	
	public static void putParam(Map params,Object key,Object value) throws ParamException {
		if(params.containsKey(key)) {
			throw new ParamException("已存在变量名"+key);
		}else if(key.equals("startId")||key.equals("endId")) {
			throw new ParamException("因变量名startId,endId与datax冲突,不能使用");
		}else {
			params.put(key, value);
		}
		
	}
	
	
	public static boolean compare(Object value1, Object value2, String relation) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		
		Object v=null;
		
		if(relation==null||relation.trim().length()==0) {
			return true;
		}
		
		if(value1==null) {
			v=value2;
		}else if(value2==null) {
			v=null;
		}else if(!(value2 instanceof String)) {
			Constructor<? extends Object> con = value1.getClass().getConstructor(String.class);
			v=con.newInstance(value2.toString());
		}else if(value1 instanceof Number&&value2 instanceof String) {
			Constructor<? extends Object> con = value1.getClass().getConstructor(String.class);
			v=con.newInstance(value2);
		}else {
			v=value2;
		}
		
		if(value1 instanceof Comparable) {
			Comparable v1 = (Comparable)value1;
			Comparable v2 = (Comparable)v;
			if (relation==null||relation.trim().equals("")) {
				return true;
			}else if (relation.equals("=") &&v1!=null&&v2!=null&&v1.compareTo(v2) == 0) {
				return true;
			} else if (relation.equals(">=") &&v1!=null&&v2!=null&&v1.compareTo(v2) >= 0) {
				return true;
			} else if (relation.equals("<=") &&v1!=null&&v2!=null&&v1.compareTo(v2) <= 0) {
				return true;
			} else if (relation.equals(">") &&v1!=null&&v2!=null&&v1.compareTo(v2) > 0) {
				return true;
			} else if (relation.equals("!=") &&v1!=null&&v2!=null&&v1.compareTo(v2) != 0) {
				return true;
			}else if (relation.equals("<") &&v1!=null&&v2!=null&&v1.compareTo(v2) < 0) {
				return true;
			} else if (relation.equals("isNotNull") && v1!=null) {
				return true;
			} else if (relation.equals("isNotEmpty") &&v1!=null&&v1.toString().length()!=0) {
				return true;
			} else if (relation.equals("isNull") &&v1==null) {
				return true;
			} else if (relation.equals("isEmpty") &&v1!=null&&v1.toString().length()==0) {
				return true;
			}else {
				return false;
			}
		}else if(value1==null&&relation.equals("isNull")) {
			return true;
		}else if(value1!=null&&relation.equals("isNotNull")) {
			return true;
		}else if(value1!=null&&value1 instanceof List) {
			List v1 = (List)value1;
			if (relation.equals("isEmpty") && v1.isEmpty()) {
				return true;
			}else if (relation.equals("isNotEmpty") && !v1.isEmpty()) {
				return true;
			}else {
				return false;
			}
		}else {
			return false;
		}
		
		
		

		
		

		
	}
	



}
